home *** CD-ROM | disk | FTP | other *** search
/ Aminet 50 / Aminet 50 (2002)(GTI - Schatztruhe)[!][Aug 2002].iso / Aminet / text / edit / tecoc-146.lha / bldstr.c < prev    next >
C/C++ Source or Header  |  1991-07-05  |  8KB  |  273 lines

  1. /*****************************************************************************
  2.  
  3.     BldStr()
  4.  
  5.     This function "builds" a string.  This means converting string
  6. build constructs in the input string into their intended equivalents
  7. in the output string.  The string build constructs are as follows:
  8.  
  9.     ^Q    use next character literally,  not as a string build char
  10.     ^R    use next character literally,  not as a string build char
  11.     ^V    lowercase the next character
  12.     ^V^V    lowercase all following characters
  13.     ^W    uppercase the next character
  14.     ^W^W    uppercase all following characters
  15.     ^EQq    use string in q-register q here
  16.     ^EUq    use ASCII char for number in q-register q here
  17.  
  18.     When this function is called,  CBfPtr points to the first character
  19. of the input string.  It is assumed that the string is terminated by an ESCAPE
  20. character (or something else if the calling command was @-modified).  If the
  21. string is not properly terminated this function will die with "unterminated
  22. command" when it encounters CStEnd while looking for the terminator character.
  23.  
  24.     When this function returns,  CBfPtr points to the ESCAPE which
  25. terminates the string, the built string is in the buffer pointed to by
  26. XBfBeg,  and XBfPtr points to the character after the last character in
  27. the built string.
  28.  
  29.     The commands which contain a filename (EB, EI, EN, ER and
  30. EW) use this function.  The EG command, which exits with an operating system
  31. command line, uses this function.  The O command, which jumps to a tag, uses
  32. this function.  The search commands (E_, FK, FN, FS, F_, N, S and _) use this
  33. function.
  34.  
  35. *****************************************************************************/
  36.  
  37. #include "zport.h"        /* define portability identifiers */
  38. #include "tecoc.h"        /* define general identifiers */
  39. #include "defext.h"        /* define external global variables */
  40. #include "deferr.h"        /* define identifiers for error messages */
  41. #include "dchars.h"        /* define identifiers for characters */
  42. #include "chmacs.h"        /* define character processing macros */
  43.  
  44. #if USE_PROTOTYPES
  45. static DEFAULT DoCtVW(charptr EndArg, unsigned char TmpChr);
  46. static DEFAULT DoCtE(charptr EndArg, charptr XBfEnd);
  47. #endif
  48.  
  49. static charptr BBfPtr;            /* pointer into XBf */
  50. static int CaseCv;            /* case conversion */
  51. static unsigned char WVFlag;        /* ^W or ^V flag */
  52.  
  53. static DEFAULT DoCtVW(EndArg, TmpChr)    /* do a control-V or control-W */
  54. charptr EndArg;                /* ptr to end of string argument */
  55. unsigned char TmpChr;            /* temporary character */
  56. {
  57.     DBGFEN(3,"DoCtVW",NULL);
  58.  
  59.     WVFlag = TmpChr;
  60.     if (++CBfPtr == EndArg) {        /* move past ^W or ^V,  too far? */
  61.     ErrMsg(ERR_ISS);        /* yes, illegal search string */
  62.     DBGFEX(2,DbgFNm,"FAILURE");
  63.     return FAILURE;
  64.     }
  65.     if ((*CBfPtr == '^') && ((EdFlag & ED_CARET_OK) == 0)) {
  66.     if (++CBfPtr == EndArg) {
  67.         ErrMsg(ERR_ISS);
  68.         DBGFEX(2,DbgFNm,"FAILURE");
  69.         return FAILURE;
  70.     }
  71.     TmpChr = To_Upper(*CBfPtr);
  72.     if ((TmpChr < '@') || (TmpChr > '_')) {
  73.         ErrChr(ERR_IUC, *CBfPtr);
  74.         DBGFEX(2,DbgFNm,"FAILURE");
  75.         return FAILURE;
  76.     }
  77.     TmpChr &= '\077';
  78.     } else {
  79.     TmpChr = *CBfPtr;
  80.     }
  81.     if (WVFlag == CTRL_V) {
  82.     if (TmpChr == CTRL_V) {
  83.         CaseCv = LOWER;
  84.     } else {
  85.         *BBfPtr++ = To_Lower(TmpChr);
  86.     }
  87.     } else {
  88.     if (TmpChr == CTRL_W) {
  89.         CaseCv = UPPER;
  90.     } else {
  91.         *BBfPtr++ = To_Upper(TmpChr);
  92.     }
  93.     }
  94.     WVFlag = '\0';
  95.     DBGFEX(2,DbgFNm,"SUCCESS");
  96.     return SUCCESS;
  97. }
  98.  
  99.  
  100. static DEFAULT DoCtE(EndArg, XBfEnd)    /* do a control-E */
  101. charptr EndArg;                /* ptr to end of string argument */
  102. charptr XBfEnd;                /* end of build-string buffer */
  103. {
  104.     DEFAULT    Status;            /* returned from FindQR */
  105.     charptr    TCStEn;            /* temporary holder of CStEnd */
  106.  
  107.     DBGFEN(3,"DoCtE",NULL);
  108.     if (++CBfPtr == EndArg) {        /* move past ^E,  too far? */
  109.     ErrMsg(ERR_ICE);        /* yes, illegal ^E command */
  110.     DBGFEX(2,DbgFNm,"FAILURE");
  111.     return FAILURE;
  112.     }
  113.     if ((*CBfPtr == 'Q') || (*CBfPtr == 'q')) {
  114.     if (++CBfPtr == EndArg) {
  115.         ErrMsg(ERR_ISS);
  116.         DBGFEX(2,DbgFNm,"FAILURE");
  117.         return FAILURE;
  118.     }
  119.  
  120. /*
  121.  * handle filespec buffer and search string buffer
  122.  */
  123.     if (*CBfPtr=='*' || *CBfPtr=='_') {
  124.         charptr  BufPtr, BufBeg;
  125.         if (*CBfPtr=='*') {
  126.         BufPtr=FBfPtr;
  127.         BufBeg=FBfBeg;
  128.         } else {
  129.         BufPtr=SBfPtr;
  130.         BufBeg=SBfBeg;
  131.         }
  132.         if ((BufPtr-BufBeg) > (XBfEnd-BBfPtr)) {
  133.         ErrMsg(ERR_STL);
  134.         DBGFEX(2,DbgFNm,"FAILURE");
  135.         return FAILURE;
  136.         }
  137.         MEMMOVE(BBfPtr, BufBeg, (SIZE_T)(BufPtr - BufBeg));
  138.         BBfPtr += BufPtr-BufBeg;
  139.     } else {
  140. /*
  141.  * it really must be a Q reg reference after all
  142.  */
  143.         TCStEn = CStEnd;            /* save CStEnd */
  144.         CStEnd = EndArg;
  145.         Status = FindQR();
  146.         CStEnd = TCStEn;            /* restore CStEnd */
  147.         if (Status == FAILURE) {
  148.         DBGFEX(2,DbgFNm,"FAILURE");
  149.         return FAILURE;
  150.         }
  151.         if ((QR->End_P1-QR->Start) > (XBfEnd-BBfPtr)) {
  152.         ErrMsg(ERR_STL);
  153.         DBGFEX(2,DbgFNm,"FAILURE");
  154.         return FAILURE;
  155.         }
  156.         MEMMOVE(BBfPtr, QR->Start, (SIZE_T)(QR->End_P1 - QR->Start));
  157.         BBfPtr += QR->End_P1 - QR->Start;
  158.     }
  159.     } else if ((*CBfPtr == 'U') || (*CBfPtr == 'u')) {
  160.     if (++CBfPtr == EndArg) {
  161.         ErrMsg(ERR_ISS);
  162.         DBGFEX(2,DbgFNm,"FAILURE");
  163.         return FAILURE;
  164.     }
  165.     TCStEn = CStEnd;            /* save CStEnd */
  166.     CStEnd = EndArg;
  167.     Status = FindQR();
  168.     CStEnd = TCStEn;            /* restore CStEnd */
  169.     if (Status == FAILURE) {
  170.         DBGFEX(2,DbgFNm,"FAILURE");
  171.         return FAILURE;
  172.     }
  173.     *BBfPtr++ = (char)QR->Number;
  174.     } else {
  175.     *BBfPtr++ = CTRL_E;
  176.     *BBfPtr++ = *CBfPtr;
  177.     }
  178.     DBGFEX(2,DbgFNm,"SUCCESS");
  179.     return SUCCESS;
  180. }
  181.  
  182.  
  183. DEFAULT BldStr(XBfBeg, XBfEnd, XBfPtr)        /* build a string */
  184. charptr XBfBeg;            /* beginning of build-string buffer */
  185. charptr XBfEnd;            /* end of build-string buffer */
  186. charptr (*XBfPtr);        /* pointer into build-string buffer */
  187. {
  188.     charptr    EndArg;        /* end of input string, plus 1 */
  189.     unsigned char TmpChr;    /* temporary character */
  190.  
  191.     DBGFEN(2,"BldStr",NULL);
  192.  
  193.     if (FindES(ESCAPE) == FAILURE) {    /* move CBfPtr to end of argument */
  194.     DBGFEX(2,DbgFNm,"FAILURE, FindES(ESCAPE) failed");
  195.     return FAILURE;
  196.     }
  197.  
  198.     WVFlag = '\0';        /* initialize ^W and ^V flag */
  199.     CaseCv = IniSrM;        /* initialize internal search mode */
  200.     BBfPtr = XBfBeg;        /* initialize ptr into build-string buffer */
  201.     EndArg = CBfPtr;        /* save pointer to end of argument */
  202.     CBfPtr = ArgPtr;        /* reset to beginning of argument */
  203.  
  204.     while (CBfPtr < EndArg) {
  205.     if ((*CBfPtr == '^') && ((EdFlag & ED_CARET_OK) == 0)) {
  206.         if (++CBfPtr == EndArg) {
  207.         ErrMsg(ERR_ISS);
  208.         DBGFEX(2,DbgFNm,"FAILURE, no char after ^");
  209.         return FAILURE;
  210.         }
  211.         TmpChr = To_Upper(*CBfPtr);
  212.         if ((TmpChr < '@') || (TmpChr > '_')) {
  213.         ErrChr(ERR_IUC, *CBfPtr);
  214.         DBGFEX(2,DbgFNm,"FAILURE, bad char after ^");
  215.         return FAILURE;
  216.         }
  217.         TmpChr &= '\077';
  218.     } else {
  219.         TmpChr = *CBfPtr;
  220.     }
  221.  
  222.     switch (TmpChr) {
  223.  
  224.         case CTRL_R:
  225.         case CTRL_Q:
  226.         if (++CBfPtr == EndArg) {
  227.             ErrMsg(ERR_ISS);
  228.             DBGFEX(2,DbgFNm,"FAILURE");
  229.             return FAILURE;
  230.         }
  231.         *BBfPtr++ = *CBfPtr;
  232.         break;
  233.  
  234.         case CTRL_V:
  235.         case CTRL_W:
  236.         if (DoCtVW(EndArg, TmpChr) == FAILURE) {
  237.             DBGFEX(2,DbgFNm,"FAILURE, DoCtVW failed");
  238.             return FAILURE;
  239.         }
  240.         break;
  241.  
  242.         case CTRL_E:
  243.         if (DoCtE(EndArg, XBfEnd) == FAILURE) {
  244.             DBGFEX(2,DbgFNm,"FAILURE, DoCtE failed");
  245.             return FAILURE;
  246.         }
  247.         break;
  248.  
  249.         default:
  250.         if (CaseCv == LOWER) {
  251.             TmpChr = To_Lower(TmpChr);
  252.         } else if (CaseCv == UPPER) {
  253.             TmpChr = To_Upper(TmpChr);
  254.         }
  255.         *BBfPtr++ = TmpChr;
  256.     }
  257.     if (BBfPtr > XBfEnd) {
  258.         ErrMsg(ERR_STL);    /* string too long */
  259.         DBGFEX(2,DbgFNm,"FAILURE, string too long");
  260.         return FAILURE;
  261.     }
  262.     ++CBfPtr;
  263.     }
  264.     *XBfPtr = BBfPtr;
  265.  
  266. #if DEBUGGING
  267.     sprintf(DbgSBf,"string = \"%.*s\"", (int)(BBfPtr-XBfBeg), XBfBeg);
  268.     DbgFEx(2,DbgFNm,DbgSBf);
  269. #endif
  270.  
  271.     return SUCCESS;
  272. }
  273.